package com.headStorm.concurrent.manyThread;

import cn.hutool.core.thread.ThreadUtil;

import javax.xml.transform.Source;
import java.lang.management.ThreadMXBean;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolUseDemo {


    public static void main(String[] args) {
        //newCachedThreadPoolUse();
//        ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
//        cachedThreadPool.execute(new Runnable() {
//            @Override
//            public void run() {
//                while (true){
//                    System.out.println("----hhhahhaa----");
//                }
//            }
//        });
        //newCachedThreadPoolUse();

//        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//        cachedThreadPool.execute(new Runnable() {
//            @Override
//            public void run() {
//                while (true){
//                    System.out.println("----aaaaa----");
//                }
//            }
//        });
//        cachedThreadPool.execute(new Runnable() {
//            @Override
//            public void run() {
//                while(true){
//                    System.out.println("----bbbbb----");
//                }
//            }
//        });
      //  myPool();
//        for (int i = 0; i < 4; i++) {
//            handlerTrack(i);
//        }

//        ThreadUtil.safeSleep(5000);
        //System.out.println("haha");

        ExecutorService executorService = ThreadUtil.newSingleExecutor();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("aaa");
            }
        });
    }


    public static void newCachedThreadPoolUse(){
        /***
         * newCachedThreadPool
         * 创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程
         * 线程池为无限大，当执行第二个任务时第一个任务已经完成，会复用执行第一个任务的线程，而不用每次新建线程。
         */
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(index * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            cachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    while(true){
                        System.out.println(Thread.currentThread().getName()+" : "+index);
                    }
                }
            });
        }
        cachedThreadPool.shutdown();
    }

    public static void newFixedThreadPoolUse(){
        /**
         * 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待
         * 这里支持的最大线程数是5， 也可以根据系统而定，获取系统可被利用的进程数
         * Runtime.getRuntime().availableProcessors()
         */
        ExecutorService cachedThreadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(index * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            cachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(index);
                }
            });
        }
        cachedThreadPool.shutdown();
    }

    public  static void newScheduledThreadPoolUse(){

        /**
         * 创建一个定长线程池，支持定时及周期性任务执行。
         * 定义线程池，最大线程数是5
         */
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

        //延迟执行
        scheduledThreadPool.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("delay");
            }
        }, 3, TimeUnit.SECONDS);

        //延迟1秒，并每隔3眠定期执行
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("delay 1 seconds, and excute every 3 seconds");
            }
        }, 1, 3, TimeUnit.SECONDS);

        //关于延迟执行和周期性执行我们还会想到Timer
        Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {

            }
        };
        timer.schedule(timerTask, 1000, 3000);
    }

    public  static void newSingleThreadExecutorUse(){
        /**
         * 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
         */
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(index);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    public static void myPool(){

      ExecutorService executor = new ThreadPoolExecutor(10, 10,
                60L, TimeUnit.SECONDS,
                new ArrayBlockingQueue(10));
      executor.execute(new Runnable() {
          @Override
          public void run() {
              while (true){
                  System.out.println("hahaa");
              }
          }
      });
        executor.execute(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println("bbbbbb");
                }
            }
        });
    }

   private static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    private static void handlerTrack(Integer taskId){

        singleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                AtomicInteger counter = new AtomicInteger(0);
                while (true){
                    if(counter.getAndIncrement() > 2){
                        return;
                    }
                    counter.getAndIncrement();
                    System.out.println(Thread.currentThread().getName() + " "+ taskId);
                    try {
                        Thread.currentThread().sleep(1000);
                    }catch (Exception exception){
                        exception.printStackTrace();
                    }
                }
            }
        });
    }
}
